package com.seguriapp.administration.gwt.server;

import static com.google.common.collect.Lists.newArrayList;

import java.util.List;

import net.customware.gwt.dispatch.server.ExecutionContext;
import net.customware.gwt.dispatch.shared.DispatchException;
import net.sf.json.JSONArray;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;

import org.apache.log4j.Logger;
import org.restlet.resource.ClientResource;

import com.seguriapp.administration.gwt.shared.GetUsersDataAction;
import com.seguriapp.administration.gwt.shared.GetUsersDataResult;
import com.seguriapp.common.config.GlobalConfigLoader;
import com.seguriapp.common.gwt.server.AbstractSeguriAppHandler;
import com.seguriapp.entities.User;
import com.seguriapp.util.Util;

public class GetUsersDataHandler extends AbstractSeguriAppHandler<GetUsersDataAction, GetUsersDataResult> {

  private static final Logger LOGGER = Logger.getLogger(GetUsersDataHandler.class);

  public Class<GetUsersDataAction> getActionType() {
    return GetUsersDataAction.class;
  }

  public GetUsersDataResult execute(final GetUsersDataAction action, final ExecutionContext context) throws DispatchException {

    final GetUsersDataResult result = new GetUsersDataResult();
    try {
      final String url = GlobalConfigLoader.getInstance().getGlobalConfig().getBackEndUrl().concat(GlobalConfigLoader.getInstance().getGlobalConfig().getUsersList());
      final ClientResource resource = new ClientResource(url);
      final String usersListJs = resource.post(convertDataToJsonString(action)).getText();
      LOGGER.info("Data received : \n" + usersListJs);
      result.setUsersList(getJsonDataFromString(usersListJs));
      result.setCurrentPage(action.getPage());
      result.setMaxPages(GlobalConfigLoader.getInstance().getGlobalConfig().getMaxPages());
      result.setTotalPages(getJsonTotalPages(usersListJs));
    } catch (Exception e) {
      LOGGER.error("Error al obtener los usuarios", e);
    }
    return result;
  }

  private String convertDataToJsonString(final GetUsersDataAction action) {
    final JSONObject obj = new JSONObject();
    try {
      obj.put("page", action.getPage());
      obj.put("pageSize", GlobalConfigLoader.getInstance().getGlobalConfig().getPageSize());
      obj.put("ascending", action.isAscending());
      obj.put("columnSort", action.getColumnSort());
    } catch (JSONException e) {
      LOGGER.error("Error al convertir parametros de busqueda a json", e);
    }
    LOGGER.info("Sending Data : \n" + obj.toString());
    return obj.toString();
  }

  private long getJsonTotalPages(final String usersListJs) {
    long totalPages = 0;
    final JSONObject root = JSONObject.fromObject(usersListJs);
    if (root.has("totalPages")) {
      totalPages = root.getLong("totalPages");
    }
    return totalPages;
  }

  private List<User> getJsonDataFromString(final String usersListJs) {
    final List<User> usersList = newArrayList();
    final JSONObject root = JSONObject.fromObject(usersListJs);
    JSONObject jo = null;
    if (root.has("users")) {
      final JSONArray  dataArray = root.getJSONArray("users");
      if (dataArray != null) {
        for (int i = 0; i < dataArray.size(); i++) {
          jo = dataArray.getJSONObject(i);
          final User user = processjSONObject(jo);
          usersList.add(user);
        }
      }
    }
    return usersList;
  }

  private User processjSONObject(final JSONObject jo) {
    if (jo.has("id") && jo.has("username") && jo.has("administrator") && jo.has("lastDateLoggedIn")) {
      final User user = new User();
      user.setLastDateLoggedIn(Util.parseStringToDate(jo.getString("lastDateLoggedIn")));
      user.setId(jo.getLong("id"));
      user.setUsername(jo.getString("username"));
      user.setAdministrator(jo.getBoolean("administrator"));
      return user;
    }
    return null;
  }

}
